<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Spring AOP 通知类型详解</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .card-hover {
            transition: all 0.3s ease;
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
        }
        .code-block {
            background: #1e1e1e;
            border-radius: 8px;
            overflow: hidden;
        }
        .code-header {
            background: #2d2d2d;
            padding: 8px 16px;
            font-size: 12px;
            color: #888;
        }
        pre code {
            color: #d4d4d4;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
        }
        .advice-icon {
            width: 60px;
            height: 60px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 12px;
            font-size: 24px;
        }
        .timeline-dot {
            width: 16px;
            height: 16px;
            border-radius: 50%;
            background: #667eea;
            position: relative;
        }
        .timeline-line {
            width: 2px;
            background: #e5e7eb;
            position: absolute;
            top: 16px;
            bottom: -100%;
            left: 50%;
            transform: translateX(-50%);
        }
        .drop-cap {
            float: left;
            font-size: 4rem;
            line-height: 1;
            font-weight: 700;
            margin-right: 0.5rem;
            color: #667eea;
            font-family: 'Noto Serif SC', serif;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20">
        <div class="container mx-auto px-6">
            <div class="max-w-4xl mx-auto text-center">
                <h1 class="text-5xl font-bold mb-6">Spring AOP 通知类型</h1>
                <p class="text-xl opacity-90 leading-relaxed">掌握面向切面编程的核心概念，优雅实现横切关注点</p>
                <div class="mt-8 flex justify-center space-x-4">
                    <span class="bg-white bg-opacity-20 px-4 py-2 rounded-full text-sm">
                        <i class="fas fa-code mr-2"></i>5种通知类型
                    </span>
                    <span class="bg-white bg-opacity-20 px-4 py-2 rounded-full text-sm">
                        <i class="fas fa-layer-group mr-2"></i>AOP核心概念
                    </span>
                </div>
            </div>
        </div>
    </section>

    <!-- Introduction Section -->
    <section class="py-16">
        <div class="container mx-auto px-6">
            <div class="max-w-4xl mx-auto">
                <div class="bg-white rounded-2xl shadow-lg p-10">
                    <p class="text-lg leading-relaxed text-gray-700">
                        <span class="drop-cap">在</span>Spring 框架中，通知（Advice）是 AOP（面向切面编程）的核心概念之一。通知是指在特定的连接点（例如方法调用）上执行的代码。Spring AOP 支持多种类型的通知，通过这些通知，开发者可以在不修改目标方法代码的情况下，插入横切关注点，如日志记录、安全检查、性能监控等。了解和掌握这些通知类型能够帮助开发者更好地利用 Spring AOP 实现灵活的应用程序功能。
                    </p>
                </div>
            </div>
        </div>
    </section>

    <!-- Visual Diagram -->
    <section class="py-8">
        <div class="container mx-auto px-6">
            <div class="max-w-6xl mx-auto">
                <div class="bg-white rounded-2xl shadow-lg p-10">
                    <h2 class="text-3xl font-bold text-center mb-8 text-gray-800">通知类型关系图</h2>
                    <div class="mermaid">
                        graph TD
                        A[目标方法] --> B{AOP代理}
                        B --> C[前置通知<br/>@Before]
                        B --> D[后置通知<br/>@After]
                        B --> E[返回通知<br/>@AfterReturning]
                        B --> F[异常通知<br/>@AfterThrowing]
                        B --> G[环绕通知<br/>@Around]
                        
                        C --> H[方法执行前]
                        D --> I[方法执行后]
                        E --> J[方法成功返回]
                        F --> K[方法抛出异常]
                        G --> L[完全控制]
                        
                        style A fill:#f9f,stroke:#333,stroke-width:2px
                        style B fill:#bbf,stroke:#333,stroke-width:2px
                        style C fill:#9f9,stroke:#333,stroke-width:2px
                        style D fill:#9f9,stroke:#333,stroke-width:2px
                        style E fill:#9f9,stroke:#333,stroke-width:2px
                        style F fill:#9f9,stroke:#333,stroke-width:2px
                        style G fill:#ff9,stroke:#333,stroke-width:2px
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Advice Types Section -->
    <section class="py-16">
        <div class="container mx-auto px-6">
            <div class="max-w-6xl mx-auto">
                <h2 class="text-4xl font-bold text-center mb-12 text-gray-800">五种通知类型详解</h2>
                
                <!-- Before Advice -->
                <div class="mb-12 card-hover">
                    <div class="bg-white rounded-2xl shadow-lg overflow-hidden">
                        <div class="flex">
                            <div class="w-1/3 bg-gradient-to-br from-blue-500 to-blue-600 p-8 flex items-center justify-center">
                                <div class="text-center text-white">
                                    <div class="advice-icon bg-white bg-opacity-20 mx-auto mb-4">
                                        <i class="fas fa-play"></i>
                                    </div>
                                    <h3 class="text-2xl font-bold">前置通知</h3>
                                    <p class="text-sm opacity-90 mt-2">@Before</p>
                                </div>
                            </div>
                            <div class="w-2/3 p-8">
                                <h4 class="text-xl font-bold mb-4 text-gray-800">Before Advice</h4>
                                <p class="text-gray-600 mb-4">在目标方法执行之前执行的通知。用于在目标方法之前执行某些操作，例如权限检查、日志记录等。</p>
                                <div class="code-block">
                                    <div class="code-header">Java</div>
                                    <pre class="p-4 overflow-x-auto"><code>@Before("execution(* com.ts.service.MyService.*(..))")
public void beforeAdvice(JoinPoint joinPoint) {
    System.out.println("前置通知：方法执行前的操作");
}</code></pre>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- After Advice -->
                <div class="mb-12 card-hover">
                    <div class="bg-white rounded-2xl shadow-lg overflow-hidden">
                        <div class="flex">
                            <div class="w-1/3 bg-gradient-to-br from-green-500 to-green-600 p-8 flex items-center justify-center">
                                <div class="text-center text-white">
                                    <div class="advice-icon bg-white bg-opacity-20 mx-auto mb-4">
                                        <i class="fas fa-stop"></i>
                                    </div>
                                    <h3 class="text-2xl font-bold">后置通知</h3>
                                    <p class="text-sm opacity-90 mt-2">@After</p>
                                </div>
                            </div>
                            <div class="w-2/3 p-8">
                                <h4 class="text-xl font-bold mb-4 text-gray-800">After Advice</h4>
                                <p class="text-gray-600 mb-4">在目标方法执行之后执行的通知，无论目标方法执行成功还是失败。通常用于资源释放、清理工作等。</p>
                                <div class="code-block">
                                    <div class="code-header">Java</div>
                                    <pre class="p-4 overflow-x-auto"><code>@After("execution(* com.ts.service.MyService.*(..))")
public void afterAdvice(JoinPoint joinPoint) {
    System.out.println("后置通知：方法执行后的操作");
}</code></pre>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- After Returning Advice -->
                <div class="mb-12 card-hover">
                    <div class="bg-white rounded-2xl shadow-lg overflow-hidden">
                        <div class="flex">
                            <div class="w-1/3 bg-gradient-to-br from-purple-500 to-purple-600 p-8 flex items-center justify-center">
                                <div class="text-center text-white">
                                    <div class="advice-icon bg-white bg-opacity-20 mx-auto mb-4">
                                        <i class="fas fa-check-circle"></i>
                                    </div>
                                    <h3 class="text-2xl font-bold">返回通知</h3>
                                    <p class="text-sm opacity-90 mt-2">@AfterReturning</p>
                                </div>
                            </div>
                            <div class="w-2/3 p-8">
                                <h4 class="text-xl font-bold mb-4 text-gray-800">After Returning Advice</h4>
                                <p class="text-gray-600 mb-4">在目标方法成功执行之后执行的通知。用于处理目标方法成功返回后的逻辑，例如对返回结果的处理或日志记录。</p>
                                <div class="code-block">
                                    <div class="code-header">Java</div>
                                    <pre class="p-4 overflow-x-auto"><code>@AfterReturning(pointcut = "execution(* com.ts.service.MyService.*(..))", returning = "result")
public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
    System.out.println("返回通知：方法返回值为：" + result);
}</code></pre>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- After Throwing Advice -->
                <div class="mb-12 card-hover">
                    <div class="bg-white rounded-2xl shadow-lg overflow-hidden">
                        <div class="flex">
                            <div class="w-1/3 bg-gradient-to-br from-red-500 to-red-600 p-8 flex items-center justify-center">
                                <div class="text-center text-white">
                                    <div class="advice-icon bg-white bg-opacity-20 mx-auto mb-4">
                                        <i class="fas fa-exclamation-triangle"></i>
                                    </div>
                                    <h3 class="text-2xl font-bold">异常通知</h3>
                                    <p class="text-sm opacity-90 mt-2">@AfterThrowing</p>
                                </div>
                            </div>
                            <div class="w-2/3 p-8">
                                <h4 class="text-xl font-bold mb-4 text-gray-800">After Throwing Advice</h4>
                                <p class="text-gray-600 mb-4">在目标方法抛出异常时执行的通知。用于异常处理、日志记录或通知发送等。</p>
                                <div class="code-block">
                                    <div class="code-header">Java</div>
                                    <pre class="p-4 overflow-x-auto"><code>@AfterThrowing(pointcut = "execution(* com.ts.service.MyService.*(..))", throwing = "exception")
public void afterThrowingAdvice(JoinPoint joinPoint, Exception exception) {
    System.out.println("异常通知：方法抛出了异常：" + exception);
}</code></pre>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- Around Advice -->
                <div class="mb-12 card-hover">
                    <div class="bg-white rounded-2xl shadow-lg overflow-hidden">
                        <div class="flex">
                            <div class="w-1/3 bg-gradient-to-br from-yellow-500 to-orange-600 p-8 flex items-center justify-center">
                                <div class="text-center text-white">
                                    <div class="advice-icon bg-white bg-opacity-20 mx-auto mb-4">
                                        <i class="